﻿#pragma once

#include "Appender.h"

namespace log4lite {
	
	class FileAppender : public Appender 
	{
	public:
		FileAppender(const tstring& filename, std::ios::open_mode mode = std::ios::trunc, bool immediateFlush = true) 
			: _filename(filename)
			, _immediateFlush(immediateFlush)
		{
			open(mode);
		}

		~FileAppender()
		{
			close();
		}

	protected:
		virtual void append(const LogItem& item)
		{
		    if(!_ofs.good()) {
				if(!reopen()) {
					tcout << T_TEXT("file is not open: ") << _filename;
					return;
				}
			}

			_layout->formatAndAppend(_ofs, item);
			if (_immediateFlush) {
				_ofs.flush();
			}
		}

	private:
		void open(std::ios::openmode mode)
		{
			_ofs.open(_filename.c_str(), mode);
			if (!_ofs.good()) {
				tcout << T_TEXT("Unable to open file: ") << _filename;
			}
		}
		
		bool reopen()
		{
			_ofs.close();

			_ofs.clear(); // reset flags since the C++ standard specified that all the
			// flags should remain unchanged on a close

			open(std::ios::app);
			if(_ofs.good())
				return true;
			return false;
		}
		
		void close()
		{
			_ofs.close();
		}

	protected:
		tstring _filename;
		tofstream _ofs;
		bool _immediateFlush;
	};
	
} // namespace log